/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.gc.cscott.verify.common;

import com.gc.cscott.verify.JavaTaskOutputVerifier;
import com.gc.cscott.verify.OutputVerifier.VerifiedOutput;
import com.google.common.base.Preconditions;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 *
 * @author root
 */
public class DomUDorogiVerifier implements JavaTaskOutputVerifier {

    public VerifiedOutput verify(String inputText, String outputText, String validationHintText) {
        Preconditions.checkNotNull(inputText);
        Preconditions.checkNotNull(outputText);
        Preconditions.checkNotNull(validationHintText);
        final List<Line2D> lines = new ArrayList<Line2D>();
        final String[] inputLines = inputText.split("\n");
        final int count = Integer.parseInt(inputLines[0].trim());
        for(int i = 0;i<count;i++){
            final Line2D line = parseLine(inputLines[1+i].trim());
            lines.add(line);
        }
        final Point2D user;
        try {
            user = parsePoint(outputText);
        } catch (Exception e) {
            return VerifiedOutput.outputIsWrong("Wrong format: " + e.getMessage());
        }

        final Point2D correct = parsePoint(validationHintText);
        double maxUser = measureDistance(user, lines);
        double maxCorrect = measureDistance(correct, lines);
        //log.

        double divider = Math.max(1, maxCorrect);
        double precision = Math.abs(maxUser-maxCorrect) / divider;
        if (precision < 0.000005) {
            return VerifiedOutput.outputIsCorrect();
        } else {
            if (maxUser<maxCorrect){
                throw new Error("user " + user + ", correct " + correct + ", failure " + precision+", maxuser="+maxUser+", maxcorr="+maxCorrect);
            }
            return VerifiedOutput.outputIsWrong("user " + user + ", correct " + correct + ", failure " + precision+", maxuser="+maxUser+", maxcorr="+maxCorrect);
        }
    }

    double measureDistance(Point2D p, List<Line2D> lines){
        double max = -1.0;
        for(Line2D line:lines){
            double distance = Math.sqrt(line.ptLineDist(p));
            if (distance>max){
                max = distance;
            }
        }
        Preconditions.checkArgument(max>=0);
        return max;
    }

//    double measureDistance(Point2D p, List<Line2D> lines){
//        double result = 0.0;
//        for(Line2D line:lines){
//            double distance = Math.sqrt(line.ptLineDist(p));
//            result+=distance;
//        }
//        return result;
//    }

    Point2D parsePoint(String line) {
        line = line.trim();
        String[] items = line.split("\\s+");
        String x = items[0];
        String y = items[1];
        return new Point2D.Double(Double.parseDouble(x), Double.parseDouble(y));
    }

    Line2D parseLine(String line) {
        String[] items = line.split("\\s+");
        int x1 = Integer.parseInt(items[0]);
        int y1 = Integer.parseInt(items[1]);
        int x2 = Integer.parseInt(items[2]);
        int y2 = Integer.parseInt(items[3]);
        return new Line2D.Double(new Point2D.Double(x1, y1), new Point2D.Double(x2, y2));
    }
}
